// 'players'
function Player(id, name, growth, kill, role){
    this.player_id = id;
    this.player_name = name;
    this.player_points_growth = growth;
    this.player_points_kill = kill;
    this.player_role = role;
}

// 'bases'
function Base(id, x_coordinate, y_coordinate, resources, num_ants){
    var self = this;
    self.base_id = id;
    self.base_id_sel = 'base_sel_' + self.base_id;
    self.x_coordinate = x_coordinate;
    self.y_coordinate = y_coordinate;
    self.base_name = "(" + self.x_coordinate + ", " + self.y_coordinate + ")";
    self.type_ants = ['Recolectoras', 'Soldados', 'Escudos', 'Bulldogs', 'Tejedoras', 'Princesas'];
    self.icons_ants = ['/static/img/icons_ants/Ant-16-W.png', '/static/img/icons_ants/Ant-16-OO.png', '/static/img/icons_ants/Ant-16-OD.png', '/static/img/icons_ants/Ant-16-FO.png', '/static/img/icons_ants/Ant-16-FD.png', '/static/img/icons_ants/Ant-16-Q.png'];
    self.num_ants = num_ants;
    self.resources = resources;
}

// 'map'
function BaseMap(base_id, x_coordinate, y_coordinate, player_id, player_name, player_role, player_points_growth, player_points_kill, level, bonus, resources_limit){
    var self = this;
    self.base_id = base_id;
    self.base_id_map = 'base_map_' + self.base_id;
    self.base_id_map_action = 'base_map_action_' + self.base_id;
    self.x_coordinate = x_coordinate;
    self.y_coordinate = y_coordinate;
    self.base_name = "(" + self.x_coordinate + ", " + self.y_coordinate + ")";
    self.player_id = player_id; // QUIZÁS SOBRE ESTE CAMPO... ANALIZAR... ^_^
    self.player_name = player_name;
    self.player_role = player_role;
    self.player_points_growth = player_points_growth;
    self.player_points_kill = player_points_kill;
    self.level = level;
    self.resources_limit = resources_limit;
    self.bonus = bonus;
}

// 'time_event_attack'
function EventAttack(event_attack_id, base_origin_id, base_origin_x, base_origin_y, player_origin_name, base_finish_id, base_finish_x, base_finish_y, player_finish_name, num_ants, resources, type_movement){
    var self = this;
    self.event_attack_id = event_attack_id;
    self.sel_event_id = type_movement + "_" + event_attack_id;

    self.base_origin_id = base_origin_id; // hace falta?
    self.base_origin_x = base_origin_x;
    self.base_origin_y = base_origin_y;
    self.base_origin_name = "(" + self.base_origin_x + ", " + self.base_origin_y + ")";
    self.player_origin_name = player_origin_name;

    self.base_finish_id = base_finish_id; // hace falta?
    self.base_finish_x = base_finish_x;
    self.base_finish_y = base_finish_y;
    self.base_finish_name = "(" + self.base_finish_x + ", " + self.base_finish_y + ")";
    self.player_finish_name = player_finish_name;

    self.resources = resources;

    self.type_ants = ['Recolectoras', 'Soldados', 'Escudos', 'Bulldogs', 'Tejedoras', 'Princesas'];
    self.num_ants = num_ants;
    self.type_movement = type_movement; // { attack_start, attack_receive, attack_back }
}

// 'time_event_uphold'
function EventUphold(event_uphold_id, base_origin_id, base_origin_x, base_origin_y, player_origin_name, base_finish_id, base_finish_x, base_finish_y, player_finish_name, num_ants, resources, type_movement){
    var self = this;
    self.event_uphold_id = event_uphold_id;
    self.sel_event_id = type_movement + "_" + event_uphold_id;

    self.base_origin_id = base_origin_id; // hace falta?
    self.base_origin_x = base_origin_x;
    self.base_origin_y = base_origin_y;
    self.base_origin_name = "(" + self.base_origin_x + ", " + self.base_origin_y + ")";
    self.player_origin_name = player_origin_name;

    self.base_finish_id = base_finish_id; // hace falta?
    self.base_finish_x = base_finish_x;
    self.base_finish_y = base_finish_y;
    self.base_finish_name = "(" + self.base_finish_x + ", " + self.base_finish_y + ")";
    self.player_finish_name = player_finish_name;

    self.resources = resources;

    self.type_ants = ['Recolectoras', 'Soldados', 'Escudos', 'Bulldogs', 'Tejedoras', 'Princesas'];
    self.num_ants = num_ants;
    self.type_movement = type_movement; // { uphold_start, uphold_receive, uphold_back }
}

// 'time_event_resources'
function EventResource(event_resource_id, base_origin_id, base_origin_x, base_origin_y, player_origin_name, base_finish_id, base_finish_x, base_finish_y, player_finish_name, num_workers, resources, type_movement){

    var self = this;
    self.event_resource_id = event_resource_id;
    self.sel_event_id = type_movement + "_" + event_resource_id;

    self.base_origin_id = base_origin_id; // hace falta?
    self.base_origin_x = base_origin_x;
    self.base_origin_y = base_origin_y;
    self.base_origin_name = "(" + self.base_origin_x + ", " + self.base_origin_y + ")";
    self.player_origin_name = player_origin_name;

    self.base_finish_id = base_finish_id; // hace falta?
    self.base_finish_x = base_finish_x;
    self.base_finish_y = base_finish_y;
    self.base_finish_name = "(" + self.base_finish_x + ", " + self.base_finish_y + ")";
    self.player_finish_name = player_finish_name;

    self.num_workers = num_workers;
    self.resources = resources;
    
    // self.seconds
    // self.tiempo_momento_actual

    self.type_movement = type_movement; // {resource_start, resource_receive, resource_back}
}

// 'battle_report'
function BattleReport(report_id, date_start_game, date_battle_report, player_start_name, base_start_x, base_start_y, ants_attack_start, ants_attack_finish, ants_attack_deads, player_finish_name, base_finish_x, base_finish_y, ants_defend_start, ants_defend_finish, ants_defend_deads, info){

    var self = this;
    self.report_id = report_id;
    self.report_id_html = "#" + self.report_id;

    self.date_start_game = date_start_game;
    self.date_battle_report = date_battle_report;
    
    self.player_start_name = player_start_name;
    self.player_finish_name = player_finish_name;

    self.base_start_x = base_start_x;
    self.base_start_y = base_start_y;
    self.base_finish_x = base_finish_x;
    self.base_finish_y = base_finish_y;

    self.ants_attack_start = ants_attack_start;
    self.ants_attack_finish = ants_attack_finish;
    self.ants_attack_deads = ants_attack_deads;

    self.ants_defend_start = ants_defend_start;
    self.ants_defend_finish = ants_defend_finish;
    self.ants_defend_deads = ants_defend_deads;

    self.ants_icons = ['/static/img/icons_ants/Ant-16-W.png', '/static/img/icons_ants/Ant-16-OO.png', '/static/img/icons_ants/Ant-16-OD.png', '/static/img/icons_ants/Ant-16-FO.png', '/static/img/icons_ants/Ant-16-FD.png', '/static/img/icons_ants/Ant-16-Q.png'];

    self.info = info;
    self.issue = self.player_start_name + " (" + self.base_start_x + ", " + self.base_start_y + ") vs " + self.player_finish_name + " (" + self.base_finish_x + ", " + self.base_finish_y + ")";
}


// 'battle_report'
function MovementReport(report_id, date_start_game, date_battle_report, player_start_name, base_start_x, base_start_y, player_finish_name, base_finish_x, base_finish_y, info){

    var self = this;
    self.report_id = report_id;
    self.report_id_html = "#" + self.report_id;

    self.date_start_game = date_start_game;
    self.date_battle_report = date_battle_report;
    
    self.player_start_name = player_start_name;
    self.player_finish_name = player_finish_name;

    self.base_start_x = base_start_x;
    self.base_start_y = base_start_y;
    self.base_finish_x = base_finish_x;
    self.base_finish_y = base_finish_y;

    self.info = info;
    self.issue = self.player_start_name + " (" + self.base_start_x + ", " + self.base_start_y + ") envía recursos a " + self.player_finish_name + " (" + self.base_finish_x + ", " + self.base_finish_y + ")";
}


// 'uphold_report'
function UpholdReport(report_id, date_start_game, date_battle_report, player_start_name, base_start_x, base_start_y, player_finish_name, base_finish_x, base_finish_y, ants_uphold_init, ants_uphold_finish, info){

    var self = this;
    self.report_id = report_id;
    self.report_id_html = "#" + self.report_id;

    self.date_start_game = date_start_game;
    self.date_battle_report = date_battle_report;
    
    self.player_start_name = player_start_name;
    self.player_finish_name = player_finish_name;

    self.base_start_x = base_start_x;
    self.base_start_y = base_start_y;
    self.base_finish_x = base_finish_x;
    self.base_finish_y = base_finish_y;

    self.ants_uphold_init = ants_uphold_init;
    self.ants_uphold_finish = ants_uphold_finish;

    self.ants_icons = ['/static/img/icons_ants/Ant-16-W.png', '/static/img/icons_ants/Ant-16-OO.png', '/static/img/icons_ants/Ant-16-OD.png', '/static/img/icons_ants/Ant-16-FO.png', '/static/img/icons_ants/Ant-16-FD.png', '/static/img/icons_ants/Ant-16-Q.png'];

    self.info = info;
    self.issue = self.player_start_name + " (" + self.base_start_x + ", " + self.base_start_y + ") apoya a " + self.player_finish_name + " (" + self.base_finish_x + ", " + self.base_finish_y + ")";
}


function Message(name, message, date){
    var self = this;
    self.name = name;
    self.message = message;
    self.date = date;
}

function GameViewModel(){
    var self = this;
    
    // GAMES

    // self.base_selected = -1; // meter una function aquí... para cuando cambie de base...
    // self.base_selected = ko.observable();

    self.base_selected = null;
    self.base_map_selected = null;
    self.player_id = null;
    self.player_is_speed_bonus = false;
    self.player_is_speed_bonus_base = false;

    self.badge_reports = 0;
    self.badge_events = 0;
    self.badge_chats = 0;


    /*
    self.resources_totals = ko.computed(function(){
        var total = 0;
        for(var i in this.bases){
            total += i.resources;
        }
        return total;
    }, this);
    */

    // update a mano...
    /*
    self.bases_refresh = function(){
        var data = self.bases().slice(0);
        self.bases([]);
        self.bases(data);
    };*/

    self.bases = ko.observableArray([]);

    self.clear_bases = function() {
        self.bases([]);
    }

    // Add or Update a Base
    self.add_base = function(base) {
        var match = ko.utils.arrayFirst(self.bases(), function(item) {
            return base.base_id === item.base_id;
        });

        if (match) {
            self.bases.remove(match);
        }
        self.bases.push(base);

        /*
        self.bases.valueWillMutate();
        if (match) { // update
            debugger;
            match.resources = base.resources;
            match.num_ants = base.num_ants;

            // parchazo
            // base_auxiliar = new Base(-1, -1, -1, -1, -1);
            // self.bases.push(base_auxiliar);
            // self.bases.remove(base_auxiliar);
        } else { // add
            self.bases.push(base);
        }
        self.bases.valueHasMutated();
        self.bases_refresh();
        */
    }
    
    self.remove_base = function(base){
        this.bases.remove(base);
    }

    // PLAYERS

    self.players = ko.observableArray([]);
    
    // Add or Update a Player
    self.add_player = function(player){
        var match = ko.utils.arrayFirst(self.players(), function(item) {
            return player.player_id === item.player_id;
        });
        /*
        if (match) { // update
            match.player_points_growth = player.player_points_growth;
            match.player_points_kill = player.player_points_kill;
        } else { // add
            self.players.push(player);
        }
        */

        if (match){
            self.players.remove(match);
        }
        self.players.push(player);

    };
    
    self.remove_player = function(player) {
        self.players.remove(player); 
    }
    
    // No entra
    self.players.sort(function(l, r) {
        debugger;
        return l.player_points_growth <= r.player_points_growth ? 1: -1;
    });


    // BASES MAP
    self.bases_map = ko.observableArray([]);
    
    self.add_base_map = function(base_map){
        var match = ko.utils.arrayFirst(self.bases_map(), function(item) {
            return base_map.base_id === item.base_id;
        });
        if (match){
            self.bases_map.remove(match);
        }
        
        // New base
        
        // TODO: Distinguir si se trata de una base de un compañero de equipo.
        var fore = me.game.currentLevel.getLayers()[0];
        var back = me.game.currentLevel.getLayers()[1];
        if(base_map.player_id == null){ // Free Bases
            //back.setTile(base_map.x_coordinate, base_map.y_coordinate, fore.getTileId(65, 0));
            back.setTile(base_map.x_coordinate, base_map.y_coordinate, fore.getTileId(0, 0));
        } else { // Occupied bases
            if (base_map.player_id == game_vc.player_id) { // bases propias
                back.setTile(base_map.x_coordinate, base_map.y_coordinate, fore.getTileId(0, 33));
            } else { // bases enemigas
                back.setTile(base_map.x_coordinate, base_map.y_coordinate, fore.getTileId(33, 0));
            } // elif -> bases del equipo ¿?
        }
        me.game.sort();

        self.bases_map.push(base_map);
    };
    
    self.remove_base_map = function(base_map) {
        self.bases_map.remove(base_map);
    };

    self.get_base_map = function(x_coordinate, y_coordinate){
        var match = ko.utils.arrayFirst(self.bases_map(), function(item) {
            return x_coordinate === item.x_coordinate && y_coordinate === item.y_coordinate;
        });

        if (match){
            return match;
        } else {
            return null;
        }
    };

    self.get_base_map_id = function(base_map_id){
        var match = ko.utils.arrayFirst(self.bases_map(), function(item) {
            return base_map_id === item.base_id;
        });

        if (match){
            return match;
        } else {
            return null;
        }

    };

    // EVENTS ATTACKS
    self.events_attacks = ko.observableArray([]);
    
    self.get_event_attack = function(type_id){
        var match = ko.utils.arrayFirst(self.events_attacks(), function(item) {
            return type_id === item.sel_event_id;
        });

        if (match){
            return match;
        } else {
            return null;
        }

    };
    
    self.add_event_attack = function(event_attack){
        var match = ko.utils.arrayFirst(self.events_attacks(), function(item) {
            return event_attack.sel_event_id === item.sel_event_id;
        });
        if (match){
            self.events_attacks.remove(match);
        }
        self.events_attacks.push(event_attack);
    };
    
    self.remove_event_attack = function(event_attack) {
        self.events_attacks.remove(event_attack);
    };


    // EVENTS UPHOLDS
    self.events_upholds = ko.observableArray([]);
    
    self.get_event_uphold = function(type_id){
        var match = ko.utils.arrayFirst(self.events_upholds(), function(item) {
            return type_id === item.sel_event_id;
        });

        if (match){
            return match;
        } else {
            return null;
        }

    };
    
    self.add_event_uphold = function(event_uphold){
        var match = ko.utils.arrayFirst(self.events_upholds(), function(item) {
            return event_uphold.sel_event_id === item.sel_event_id;
        });
        if (match){
            self.events_upholds.remove(match);
        }
        self.events_upholds.push(event_uphold);
    };
    
    self.remove_event_uphold = function(event_uphold) {
        self.events_upholds.remove(event_uphold);
    };


    // BATTLE REPORTS
    self.battle_reports = ko.observableArray([]);
    
    self.get_battle_report = function(report_id){
        var match = ko.utils.arrayFirst(self.battle_reports(), function(item) {
            return report_id === item.report_id;
        });

        if (match){
            return match;
        } else {
            return null;
        }

    };
    
    self.add_battle_report = function(battle_report){
        var match = ko.utils.arrayFirst(self.battle_reports(), function(item) {
            return battle_report.report_id === item.report_id;
        });
        if (match){
            self.battle_reports.remove(match);
        }
        self.battle_reports.push(battle_report);
    };
    
    self.remove_battle_report = function(battle_report) {
        self.battle_reports.remove(battle_report);
    };


    // MOVEMENT REPORTS
    self.movement_reports = ko.observableArray([]);
    
    self.get_movement_report = function(report_id){
        var match = ko.utils.arrayFirst(self.movement_reports(), function(item) {
            return report_id === item.report_id;
        });

        if (match){
            return match;
        } else {
            return null;
        }

    };
    
    self.add_movement_report = function(movement_report){
        var match = ko.utils.arrayFirst(self.movement_reports(), function(item) {
            return movement_report.report_id === item.report_id;
        });
        if (match){
            self.movement_reports.remove(match);
        }
        self.movement_reports.push(movement_report);
    };
    
    self.remove_movement_report = function(movement_report) {
        self.movement_reports.remove(movement_report);
    };


    // UPHOLD REPORTS
    self.uphold_reports = ko.observableArray([]);
    
    self.get_uphold_report = function(report_id){
        var match = ko.utils.arrayFirst(self.uphold_reports(), function(item) {
            return report_id === item.report_id;
        });

        if (match){
            return match;
        } else {
            return null;
        }

    };
    
    self.add_uphold_report = function(uphold_report){
        var match = ko.utils.arrayFirst(self.uphold_reports(), function(item) {
            return uphold_report.report_id === item.report_id;
        });
        if (match){
            self.uphold_reports.remove(match);
        }
        self.uphold_reports.push(uphold_report);
    };
    
    self.remove_uphold_report = function(uphold_report) {
        self.uphold_reports.remove(uphold_report);
    };



    // EVENTS MOVEMENT RESOURCES
    self.events_resources = ko.observableArray([]);
    
    self.get_event_resource = function(type_id){
        var match = ko.utils.arrayFirst(self.events_resources(), function(item) {
            return type_id === item.sel_event_id;
        });

        if (match){
            return match;
        } else {
            return null;
        }

    };
    
    self.add_event_resource = function(event_resource){
        var match = ko.utils.arrayFirst(self.events_resources(), function(item) {
            return event_resource.sel_event_id === item.sel_event_id;
        });
        if (match){
            self.events_resources.remove(match);
        }
        self.events_resources.push(event_resource);
    };
    
    self.remove_event_resource = function(event_resource) {
        self.events_resources.remove(event_resource);
    };

    // MESSAGES
    
    self.messages = ko.observableArray([]);

    self.add_message = function(message) {
        self.messages.push(message);
    }

}

